package com.winit.common.util.treeUtils;

import org.springframework.util.ReflectionUtils;

import javax.annotation.Nullable;
import java.lang.reflect.Field;

public class TreeUtil {

    public static BaseTree getTree(Object object){
        if (null == object){
            return null;
        }
        BaseTree baseTree = new BaseTree();
        ReflectionUtils.doWithFields(object.getClass(), new TreeFiledInjector(baseTree, object ), new TreeFiledMatcher());
        baseTree.setMetaData(object);
        NodeType nodeType = object.getClass().getAnnotation(NodeType.class);
        if (null != nodeType){
            baseTree.setNodeType(nodeType.name());
        }
        return baseTree;
    }

    public static class TreeFiledMatcher implements ReflectionUtils.FieldFilter{
        @Override
        public boolean matches(Field field) {
            NodeElement nodeElement =  field.getAnnotation(NodeElement.class);
            if (nodeElement == null){
                return false;
            }
            return true;
        }
    }

    public static class TreeFiledInjector implements ReflectionUtils.FieldCallback {
        private Object baseTree;
        private Object source;
        public TreeFiledInjector(Object baseTree, Object source){
            this.baseTree = baseTree;
            this.source = source;
        }
        @Override
        public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {
            ReflectionUtils.makeAccessible(field);
            Object filedValue = ReflectionUtils.getField(field, source);
            String[] annotationValue = field.getAnnotation(NodeElement.class).name();
            if (annotationValue != null && annotationValue.length > 0){
                for (String value: annotationValue){
                    Field targetField = ReflectionUtils.findField(baseTree.getClass(), value);
                    ReflectionUtils.makeAccessible(targetField);
                    ReflectionUtils.setField(targetField, baseTree, filedValue);
                }
            }
        }
    }
}
